package com.mcx.modules.common;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

/**
 * Created by 大雪冬至 on 2021/9/15.
 * JDK - ZLib 压缩算法工具类
 */
public class ZLibUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(ZLibUtils.class);

    /**
     * 压缩字符串.
     * 使用 UTF8 字符集解码
     *
     * @param str : 字符串 （UTF-8编码）
     *            待压缩数据
     * @return byte[] 压缩后的数据
     */
    public static byte[] compress(String str) {
        if (str == null || "".equals(str)){
            return null;
        }
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        return compress(bytes);
    }


    /**
     * 压缩
     *
     * @param data
     *            待压缩数据
     * @return byte[] 压缩后的数据
     */
    public static byte[] compress(byte[] data) {
        byte[] output = new byte[0];
        Deflater compresser = new Deflater();

        compresser.reset();
        compresser.setInput(data);
        compresser.finish();
        try(ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length)) {
            byte[] buf = new byte[1024];
            while (!compresser.finished()) {
                int i = compresser.deflate(buf);
                bos.write(buf, 0, i);
            }
            output = bos.toByteArray();
        } catch (Exception e) {
            output = data;
            LOGGER.error("compress: ",e );
        }finally {
            compresser.end();
        }
        return output;
    }

    /**
     * 压缩
     *
     * @param data
     *            待压缩数据
     *
     * @param os
     *            输出流
     */
    public static void compress(byte[] data, OutputStream os) {
        DeflaterOutputStream dos = new DeflaterOutputStream(os);
        try {
            dos.write(data, 0, data.length);

            dos.finish();

            dos.flush();
        } catch (IOException e) {
            LOGGER.error("compress: ",e );
        }
    }

    /**
     * 解压缩. (采用UTF-8编码)
     *
     * @param data
     *            待压缩的数据
     * @return String 解压缩后的字符串
     */
    public static String decompressStr(byte[] data) {
        byte[] decompress = decompress(data);
        return new String(decompress,StandardCharsets.UTF_8);
    }

    /**
     * 解压缩
     *
     * @param data
     *            待压缩的数据
     * @return byte[] 解压缩后的数据
     */
    public static byte[] decompress(byte[] data) {
        byte[] output = new byte[0];

        Inflater decompresser = new Inflater();
        decompresser.reset();
        decompresser.setInput(data);

        try(ByteArrayOutputStream o = new ByteArrayOutputStream(data.length)) {
            byte[] buf = new byte[1024];
            while (!decompresser.finished()) {
                int i = decompresser.inflate(buf);
                o.write(buf, 0, i);
            }
            output = o.toByteArray();
        } catch (Exception e) {
            output = data;
            LOGGER.error("compress: ",e );
        } finally {
            decompresser.end();
        }

        return output;
    }

    /**
     * 解压缩
     *
     * @param is 输入流
     * @return byte[] 解压缩后的数据
     */
    public static byte[] decompress(InputStream is) {
        InflaterInputStream iis = new InflaterInputStream(is);
        try(ByteArrayOutputStream o = new ByteArrayOutputStream(1024)) {
            int i = 1024;
            byte[] buf = new byte[i];

            while ((i = iis.read(buf, 0, i)) > 0) {
                o.write(buf, 0, i);
            }
            return o.toByteArray();
        } catch (IOException e) {
            LOGGER.error("compress: ",e );
        }
        return null;
    }
}


